﻿using System.Collections.Generic;
using System.Runtime.InteropServices;

namespace CatEars.Core.WinAPI
{
    /// <summary>
    /// Ras信息获取
    /// </summary>
#pragma warning disable 1591
    public static class RasInfo
    {
        /// <summary>
        /// 
        /// </summary>
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
        public struct RasEntryName      //define the struct to receive the entry name
        {
            /// <summary>
            /// 
            /// </summary>
            public int dwSize;
            /// <summary>
            /// 
            /// </summary>
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256 + 1)]
            public string szEntryName;
#if WINVER5
     public int dwFlags;
     [MarshalAs(UnmanagedType.ByValTStr,SizeConst=260+1)]
     public string szPhonebookPath;
#endif
        }

        /// <summary>
        /// 计算RasEntryName结构在非托管代码里的大小
        /// </summary>
        static int _entryNameSize = -1;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="reserved"></param>
        /// <param name="lpszPhonebook"></param>
        /// <param name="lprasentryname"></param>
        /// <param name="lpcb"></param>
        /// <param name="lpcEntries"></param>
        /// <returns></returns>
        [DllImport("rasapi32.dll", CharSet = CharSet.Auto)]
        public extern static uint RasEnumEntries(
            string reserved,              // reserved, must be NULL
            string lpszPhonebook,         // pointer to full path and file name of phone-book file
            [In, Out]RasEntryName[] lprasentryname, // buffer to receive phone-book entries
            ref int lpcb,                  // size in bytes of buffer
            out int lpcEntries             // number of entries written to buffer
        );

        /// <summary>
        /// 获取所有宽带连接的名称
        /// </summary>
        /// <returns></returns>
        public static List<string> GetAllRasEntryName()
        {
            List<string> list = new List<string>();
            int lpSize = 0;

            //计算RasEntryName结构在非托管代码里的大小
            if (_entryNameSize < 0)
            {
                _entryNameSize = Marshal.SizeOf(typeof(RasEntryName));
            }

            // 声明一个只有一个元素的RASENTRYNAME结构的数组。
            RasEntryName[] names = null;
            int lpNames = 1;
            lpSize = lpNames * _entryNameSize;
            names = new RasEntryName[lpNames];
            // 设置第一个元素的结构体的大小(现在只有一个)   
            names[0].dwSize = _entryNameSize;

            // 执行RasEnumEntries,执行完成后，
            // lpcEntries将会等于实际电话本里的条目数(如果使用前面的例子，那么这个条目数为2(adsl1和adsl2))
            // lpcb将是实际需要的缓冲区大小  
            // 如果lpcEntries>1  返回值(num3)将会是ERROR_BUFFER_TOO_SMALL
            // 因为目前我们的缓冲区只能容纳一个RASENTRYNAME结构(RASENTRYNAME[] lprasentryname = new RASENTRYNAME[1]; )
            // 而如果电话本里有二个条目时，自然就会报缓冲区太小了。    
            uint retval = RasEnumEntries(null, null, names, ref lpSize, out lpNames);

            //if we have more than one connection, we need to do it again
            if (lpNames > 1)
            {
                names = new RasEntryName[lpNames];
                for (int i = 0; i < names.Length; i++)
                {
                    names[i].dwSize = _entryNameSize;
                }
                retval = RasEnumEntries(null, null, names, ref lpSize, out lpNames);
            }

            if (lpNames > 0)
            {
                for (int i = 0; i < names.Length; i++)
                {
                    list.Add(names[i].szEntryName);
                }
            }
            return list;
        }
    }
}
